package customerEnter.Frame.JDBCDao.util;

import static com.google.common.collect.Maps.newHashMap;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

import customerEnter.Frame.Annotation.FrameDataSourceController;
import customerEnter.Frame.Annotation.FrameOneToMay;
import customerEnter.Frame.Annotation.FrameOneToOne;
import customerEnter.Frame.Annotation.FrameRedisCache;
import customerEnter.Frame.DaoDataTransmission.DaoFrameDMLBaseTransmission;
import customerEnter.Frame.DaoDataTransmission.DaoFramePameTransmission;
import customerEnter.Frame.DaoDataTransmission.FramAboutMay;
import customerEnter.Frame.DaoDataTransmission.SqlPrecompileModel;
import customerEnter.Frame.DaoDataTransmission.SqlPrecompileParameter;
import customerEnter.Frame.DaoDataTransmission.WebAppsInfo;
import customerEnter.Frame.Enum.FrameDataSqlDMLUse;
import customerEnter.Frame.Error.FramErrorProcessing;
import customerEnter.Frame.JDBCDao.Interface.DaoFrameSqlProcessingInterface;
import customerEnter.Frame.JDBCDao.Interface.DaoFrameUseTypeInterface;
import customerEnter.Frame.JDBCDao.Interface.SqlExistenceResult;
import customerEnter.Frame.JDBCDao.Interface.SqlPrecompileInterface;
import customerEnter.Frame.JDBCDao.Interface.SqlPrecompileParameterInterface;
import customerEnter.Frame.JDBCDao.JdbcTemplate.IcyDataTemplate;
import customerEnter.Frame.JDBCDao.SqlExecutive.SqlExistenceDeleteObject;
import customerEnter.Frame.JDBCDao.SqlExecutive.SqlExistenceInsertBachtObject;
import customerEnter.Frame.JDBCDao.SqlExecutive.SqlExistenceInsertObject;
import customerEnter.Frame.JDBCDao.SqlExecutive.SqlExistenceResultObject;
import customerEnter.Frame.JDBCDao.SqlExecutive.SqlExistenceUpdateBachtObject;
import customerEnter.Frame.JDBCDao.SqlExecutive.SqlExistenceUpdateObject;
import customerEnter.Frame.JDBCDao.SqlProcessing.SqlServer.DaoFrameSqlProcessingDeleteImpl;
import customerEnter.Frame.JDBCDao.SqlProcessing.SqlServer.DaoFrameSqlProcessingInsertBatchImpl;
import customerEnter.Frame.JDBCDao.SqlProcessing.SqlServer.DaoFrameSqlProcessingInsertImpl;
import customerEnter.Frame.JDBCDao.SqlProcessing.SqlServer.DaoFrameSqlProcessingSelectListImpl;
import customerEnter.Frame.JDBCDao.SqlProcessing.SqlServer.DaoFrameSqlProcessingSelectObjectImpl;
import customerEnter.Frame.JDBCDao.SqlProcessing.SqlServer.DaoFrameSqlProcessingSelectOneOrMayListImpl;
import customerEnter.Frame.JDBCDao.SqlProcessing.SqlServer.DaoFrameSqlProcessingSelectPageImpl;
import customerEnter.Frame.JDBCDao.SqlProcessing.SqlServer.DaoFrameSqlProcessingUpdateBatchImpl;
import customerEnter.Frame.JDBCDao.SqlProcessing.SqlServer.DaoFrameSqlProcessingUpdateImpl;
import customerEnter.Frame.JDBCDao.SqlProcessing.mySql.DaoFrameMySqlProcessingSelectPageImpl;
import customerEnter.Frame.JDBCDao.UseQuery.DaoFrameUseTypeBeanImpl;
import customerEnter.Frame.JDBCDao.UseQuery.DaoFrameUseTypeDMLBatchImpl;
import customerEnter.Frame.JDBCDao.UseQuery.DaoFrameUseTypeDMLImpl;
import customerEnter.Frame.JDBCDao.UseQuery.DaoFrameUseTypeListMapImpl;
import customerEnter.Frame.JDBCDao.UseQuery.DaoFrameUseTypeListObjecsImpl;
import customerEnter.Frame.JDBCDao.UseQuery.DaoFrameUseTypeListTImpl;
import customerEnter.Frame.JDBCDao.UseQuery.DaoFrameUseTypeMapImpl;
import customerEnter.Frame.JDBCDao.UseQuery.DaoFrameUseTypeMayAndOneListTImpl;
import customerEnter.Frame.JDBCDao.UseQuery.DaoFrameUseTypeStringImpl;
import customerEnter.Frame.JDBCDao.UseQuery.DaoFrameUseTypeintImpl;
import customerEnter.Frame.Thread.impl.FrameStackTraceElementImpl;
import customerEnter.Frame.Thread.interfaces.FrameStackTraceElement;
import customerEnter.Frame.Utils.Log4j;
import customerEnter.Frame.bean.FrameBeansModels;
import customerEnter.Frame.bean.IcyDataTemplateDeleteBatchObject;
import customerEnter.Frame.bean.IcyDataTemplateDeleteObject;
import customerEnter.Frame.bean.IcyDataTemplateInsertBatchObject;
import customerEnter.Frame.bean.IcyDataTemplateInsertObject;
import customerEnter.Frame.bean.IcyDataTemplateUpdateBatchObject;
import customerEnter.Frame.bean.IcyDataTemplateUpdateObject;
import customerEnter.Frame.bean.IcyListMap;
import customerEnter.Frame.bean.IcyListPageMap;
import customerEnter.Frame.bean.ListObjects;
import customerEnter.tool.WhetherToEmpty;

/**
 * 
 * 
 * 类名称：DaoFrameUtil
 * 
 * 类描述：
 * 
 * 创建人：dy
 * 
 * 创建时间：2017-4-8 下午4:54:32
 * 
 */
@SuppressWarnings("rawtypes")
public class DaoFrameConntroller {

	static Map<String, DaoFrameUseTypeInterface> map = newHashMap();
	static DaoFrameUseTypeInterface daoframeUseInt;
	static DaoFrameUseTypeInterface daoframeUseString;
	static DaoFrameUseTypeInterface daoframeUseListObjecs;
	static DaoFrameUseTypeInterface daoframeUseList;
	static DaoFrameUseTypeInterface daoframeUseMap;
	static DaoFrameUseTypeInterface daoframeUseBean;
	static DaoFrameUseTypeInterface daoframeUseDmlBatch;
	static DaoFrameUseTypeInterface daoframeUseDml;
	static DaoFrameUseTypeInterface daoFrameUseTypeListMap;
	static DaoFrameUseTypeInterface daoFrameUseTypeMayAndOneListTImpl;

	// --------------sql--------------------
	static Map<FrameDataSqlDMLUse, DaoFrameSqlProcessingInterface> sqlMap = newHashMap();
	static DaoFrameSqlProcessingInterface sqlProcessingInsert;
	static DaoFrameSqlProcessingInterface sqlProcessingInsertBacth;
	static DaoFrameSqlProcessingInterface sqlProcessingUpdate;
	static DaoFrameSqlProcessingInterface sqlProcessingUpdateBacth;
	static DaoFrameSqlProcessingInterface sqlProcessingDelete;
	static DaoFrameSqlProcessingInterface sqlProcessingDeleteBacth;
	static DaoFrameSqlProcessingInterface sqlProcessingSelectPage;
	static DaoFrameSqlProcessingInterface sqlProcessingSelectList;
	static DaoFrameSqlProcessingInterface SqlProcessingSelectObject;
	static DaoFrameSqlProcessingInterface SqlProcessingSelectOneOrMayListImpl;

	// --------------mysql------------------
	static Map<FrameDataSqlDMLUse, DaoFrameSqlProcessingInterface> MysqlMap = newHashMap();
	static DaoFrameSqlProcessingInterface MysqlProcessingSelectPage;
	static DaoFrameSqlProcessingInterface MysqlProcessingSelectList;
	static DaoFrameSqlProcessingInterface MysqlProcessingInsertBacth;
	static DaoFrameSqlProcessingInterface MysqlProcessingInsert;
	static DaoFrameSqlProcessingInterface MysqlProcessingUpdate;
	static DaoFrameSqlProcessingInterface MysqlProcessingSelectObject;
	// ------------sql Execues-------------
	static Map<FrameDataSqlDMLUse, SqlExistenceResult> sqlexMap = newHashMap();

	static SqlExistenceResult sqlExistenceResult;
	static SqlExistenceResult sqlExistenceInsertObject;
	static SqlExistenceResult sqlExistenceInsertBachtObject;
	static SqlExistenceResult sqlExistenceUpdateObject;
	static SqlExistenceResult sqlExistenceUpdateBachtObject;
	static SqlExistenceResult sqlExistenceDeleteObject;
	/**
	 * ---------------------------------
	 */
	static SqlPrecompileInterface sqlPrecompileInterface;

	static {
		InitBinderDataBinderFactorySql();
		InitBinderDataBinderFactorySqlProcessing();
		InitBinderDataBinderFactoryMySqlProcessing();
		InitBinderDataBinderFactorySqlExistence();
		InitBinderDataBinderFactorySqlPrecompile();
	}

	private static void InitBinderDataBinderFactorySql() {
		daoframeUseInt = new DaoFrameUseTypeintImpl();
		daoframeUseString = new DaoFrameUseTypeStringImpl();
		daoframeUseListObjecs = new DaoFrameUseTypeListObjecsImpl();
		daoframeUseList = new DaoFrameUseTypeListTImpl();
		daoframeUseMap = new DaoFrameUseTypeMapImpl();
		daoframeUseBean = new DaoFrameUseTypeBeanImpl();
		daoframeUseDmlBatch = new DaoFrameUseTypeDMLBatchImpl();
		daoframeUseDml = new DaoFrameUseTypeDMLImpl();
		daoFrameUseTypeListMap = new DaoFrameUseTypeListMapImpl();
		daoFrameUseTypeMayAndOneListTImpl = new DaoFrameUseTypeMayAndOneListTImpl();

		map.put(Collection.class.getName(), daoframeUseList);
		map.put(String.class.getName(), daoframeUseString);
		map.put(ListObjects.class.getName(), daoframeUseListObjecs);
		map.put(Integer.class.getName(), daoframeUseInt);
		map.put(Map.class.getName(), daoframeUseMap);
		map.put(Object.class.getName(), daoframeUseBean);
		map.put(IcyListMap.class.getName(), daoFrameUseTypeListMap);
		map.put(IcyListPageMap.class.getName(), daoFrameUseTypeListMap);

		map.put(IcyDataTemplateDeleteBatchObject.class.getName(), daoframeUseDmlBatch);
		map.put(IcyDataTemplateInsertBatchObject.class.getName(), daoframeUseDmlBatch);
		map.put(IcyDataTemplateUpdateBatchObject.class.getName(), daoframeUseDmlBatch);
		map.put(IcyDataTemplateDeleteObject.class.getName(), daoframeUseDml);
		map.put(IcyDataTemplateInsertObject.class.getName(), daoframeUseDml);
		map.put(IcyDataTemplateUpdateObject.class.getName(), daoframeUseDml);
		map.put(FrameDataSqlDMLUse.SelectMayAndOne.getValue().getName(), daoFrameUseTypeMayAndOneListTImpl);
		Log4j.Log4jOutInfo("創建 Rs 處理類:" + daoframeUseInt.getClass().getName());
	}

	private static void InitBinderDataBinderFactorySqlProcessing() {
		// ------------------------SqlServer---------------------------------------
		sqlProcessingInsert = new DaoFrameSqlProcessingInsertImpl();
		sqlProcessingInsertBacth = new DaoFrameSqlProcessingInsertBatchImpl();
		sqlProcessingDelete = new DaoFrameSqlProcessingDeleteImpl();
		sqlProcessingDeleteBacth = null;
		sqlProcessingUpdate = new DaoFrameSqlProcessingUpdateImpl();
		sqlProcessingUpdateBacth = new DaoFrameSqlProcessingUpdateBatchImpl();
		sqlProcessingSelectPage = new DaoFrameSqlProcessingSelectPageImpl();
		sqlProcessingSelectList = new DaoFrameSqlProcessingSelectListImpl();
		SqlProcessingSelectObject = new DaoFrameSqlProcessingSelectObjectImpl();
		SqlProcessingSelectOneOrMayListImpl = new DaoFrameSqlProcessingSelectOneOrMayListImpl();

		sqlMap.put(FrameDataSqlDMLUse.Insert, sqlProcessingInsert);
		sqlMap.put(FrameDataSqlDMLUse.InsertBath, sqlProcessingInsertBacth);
		sqlMap.put(FrameDataSqlDMLUse.Update, sqlProcessingUpdate);
		sqlMap.put(FrameDataSqlDMLUse.UpdateBath, sqlProcessingUpdateBacth);
		sqlMap.put(FrameDataSqlDMLUse.delete, sqlProcessingDelete);
		sqlMap.put(FrameDataSqlDMLUse.deleteBath, sqlProcessingDeleteBacth);
		sqlMap.put(FrameDataSqlDMLUse.selectPage, sqlProcessingSelectPage);
		sqlMap.put(FrameDataSqlDMLUse.SelectList, sqlProcessingSelectList);
		sqlMap.put(FrameDataSqlDMLUse.bean, SqlProcessingSelectObject);
		sqlMap.put(FrameDataSqlDMLUse.SelectInteger, SqlProcessingSelectObject);
		sqlMap.put(FrameDataSqlDMLUse.SelectListObjects, SqlProcessingSelectObject);
		sqlMap.put(FrameDataSqlDMLUse.SelectMap, SqlProcessingSelectObject);
		sqlMap.put(FrameDataSqlDMLUse.SelectString, SqlProcessingSelectObject);
		sqlMap.put(FrameDataSqlDMLUse.SelectListMap, sqlProcessingSelectList);
		sqlMap.put(FrameDataSqlDMLUse.SelectListPageMap, sqlProcessingSelectPage);
		sqlMap.put(FrameDataSqlDMLUse.SelectMayAndOne, SqlProcessingSelectOneOrMayListImpl);

		Log4j.Log4jOutInfo("創建 Sql 處理類:" + sqlProcessingInsert.getClass().getName());
	}

	private static void InitBinderDataBinderFactoryMySqlProcessing() {
		// ------------------------Mysql---------------------------------------
		MysqlProcessingSelectPage = new DaoFrameMySqlProcessingSelectPageImpl();
		MysqlProcessingSelectList = new DaoFrameSqlProcessingSelectListImpl();
		MysqlProcessingInsertBacth = new DaoFrameSqlProcessingInsertBatchImpl();
		MysqlProcessingInsert = new DaoFrameSqlProcessingInsertImpl();
		MysqlProcessingUpdate = new DaoFrameSqlProcessingUpdateImpl();
		MysqlProcessingSelectObject = new DaoFrameSqlProcessingSelectObjectImpl();
		MysqlMap.put(FrameDataSqlDMLUse.selectPage, MysqlProcessingSelectPage);
		MysqlMap.put(FrameDataSqlDMLUse.SelectList, MysqlProcessingSelectList);
		MysqlMap.put(FrameDataSqlDMLUse.InsertBath, MysqlProcessingInsertBacth);
		MysqlMap.put(FrameDataSqlDMLUse.Insert, MysqlProcessingInsert);
		MysqlMap.put(FrameDataSqlDMLUse.Update, MysqlProcessingUpdate);
		MysqlMap.put(FrameDataSqlDMLUse.bean, MysqlProcessingSelectObject);
		Log4j.Log4jOutInfo("創建 MySql 處理類:" + sqlProcessingInsert.getClass().getName());
	}

	private static void InitBinderDataBinderFactorySqlExistence() {
		// -------------------------sql execues---------------
		sqlExistenceResult = new SqlExistenceResultObject();
		sqlExistenceUpdateObject = new SqlExistenceUpdateObject();
		sqlExistenceUpdateBachtObject = new SqlExistenceUpdateBachtObject();
		sqlExistenceInsertObject = new SqlExistenceInsertObject();
		sqlExistenceInsertBachtObject = new SqlExistenceInsertBachtObject();
		sqlExistenceDeleteObject = new SqlExistenceDeleteObject();

		sqlexMap.put(FrameDataSqlDMLUse.bean, sqlExistenceResult);
		sqlexMap.put(FrameDataSqlDMLUse.SelectInteger, sqlExistenceResult);
		sqlexMap.put(FrameDataSqlDMLUse.SelectListObjects, sqlExistenceResult);
		sqlexMap.put(FrameDataSqlDMLUse.SelectList, sqlExistenceResult);
		sqlexMap.put(FrameDataSqlDMLUse.SelectMap, sqlExistenceResult);
		sqlexMap.put(FrameDataSqlDMLUse.SelectString, sqlExistenceResult);
		sqlexMap.put(FrameDataSqlDMLUse.selectPage, sqlExistenceResult);
		sqlexMap.put(FrameDataSqlDMLUse.SelectListMap, sqlExistenceResult);
		sqlexMap.put(FrameDataSqlDMLUse.SelectListPageMap, sqlExistenceResult);
		sqlexMap.put(FrameDataSqlDMLUse.SelectMayAndOne, sqlExistenceResult);

		sqlexMap.put(FrameDataSqlDMLUse.Insert, sqlExistenceInsertObject);
		sqlexMap.put(FrameDataSqlDMLUse.delete, sqlExistenceDeleteObject);
		sqlexMap.put(FrameDataSqlDMLUse.Update, sqlExistenceUpdateObject);

		sqlexMap.put(FrameDataSqlDMLUse.InsertBath, sqlExistenceInsertBachtObject);

		sqlexMap.put(FrameDataSqlDMLUse.deleteBath, sqlExistenceUpdateBachtObject);
		sqlexMap.put(FrameDataSqlDMLUse.UpdateBath, sqlExistenceUpdateBachtObject);

	}

	/**
	 * 獲取 sql語句 —————— 參數 DataBase ：數據庫名稱 /DML： 數據庫操作 select insert delete
	 * update /Front ：查詢的東西/TableName:表名 /where:條件
	 */
	public static String SqlManage(String DataBase, String DML, String Front, String Rule, String TableName,
			String where) {
		return DataBase + " " + DML + " " + Front + "  " + Rule + " " + TableName + "  " + where.replace("\"", "");
	}

	/**
	 * 獲取sql
	 */
	public static String SqlAcquire(String DataBase, String DML, String Front, String Rule, String TableName,
			String where) {
		String sql = DaoFrameConntroller.SqlManage(DataBase, DML, Front, Rule, TableName, where);
		return sql.substring(1, sql.length());
	}

	/**
	 * 設置sql 和 類型 分頁
	 */
	public static <T, K> void ManageDaoFramePameTransmission(DaoFrameDMLBaseTransmission daoFrameDMLBaseTransmission,
			DaoFramePameTransmission<T, K> daoFramePameTransmission) {
		daoFramePameTransmission.SQL = DaoFrameConntroller.SqlManage(daoFrameDMLBaseTransmission.getDataBase(),
				daoFrameDMLBaseTransmission.getDML(), daoFrameDMLBaseTransmission.getFront(),
				daoFrameDMLBaseTransmission.getRule(), daoFrameDMLBaseTransmission.getTableName(),
				daoFrameDMLBaseTransmission.getWhere());
		daoFramePameTransmission.pagingParametersCount = daoFrameDMLBaseTransmission.getPagingParametersCount();
		daoFramePameTransmission.cls = daoFrameDMLBaseTransmission.getClassName();
	}

	private static void InitBinderDataBinderFactorySqlPrecompile() {
		sqlPrecompileInterface = new SqlPrecompileParameter();
	}

	public static DaoFrameUseTypeInterface getDaoFrameUseTypeInterface(String ClassName) {
		return map.get(ClassName);
	}

	public static DaoFrameSqlProcessingInterface getDaoFrameSqlProcessingInterface(
			FrameDataSqlDMLUse frameDataSqlDMLUse) {
		if ("Microsoft SQL Server JDBC Driver 3.0".equals(WebAppsInfo.webDataBase)) {
			return sqlMap.get(frameDataSqlDMLUse);
		} else if ("MySQL Connector Java".contains(WebAppsInfo.webDataBase)) {

			return MysqlMap.get(frameDataSqlDMLUse);
		} else if ("MySQL-AB JDBC Driver".contains(WebAppsInfo.webDataBase)) {

			return MysqlMap.get(frameDataSqlDMLUse);
		}
		return sqlMap.get(frameDataSqlDMLUse);
	}

	public static SqlExistenceResult sqlExistenceResultInterface(FrameDataSqlDMLUse frameDataSqlDMLUse) {
		return sqlexMap.get(frameDataSqlDMLUse);
	}

	public static <T, K> void getObject(PreparedStatement preparedStatement,
			DaoFramePameTransmission<T, K> daoFramePameTransmission) throws SQLException {
		List<SqlPrecompileModel> sIterator = daoFramePameTransmission.getSqlPrecompileParameterInterface()
				.getSqlPrecompileModels();
		Iterator<SqlPrecompileModel> iterator = sIterator.iterator();
		while (iterator.hasNext()) {
			SqlPrecompileModel sqlPrecompileModel = iterator.next();
			preparedStatement.setObject(sqlPrecompileModel.getNumber().intValue(), sqlPrecompileModel.getObject());
		}
		daoFramePameTransmission.getSqlPrecompileParameterInterface().CleanSqlPrecompileModels();
	}

	/**
	 * 修改數據的方法
	 * 
	 * @param <T>
	 * 
	 * @param <T>
	 * @param <K>
	 * @param <K>
	 * 
	 * @throws ReflectiveOperationException
	 * @throws IllegalArgumentException
	 */
	public static <T, K> void setUpdateMappingSql(PreparedStatement preparedStatement,
			DaoFramePameTransmission<T, K> daoFramePameTransmission) throws Exception {
		getObject(preparedStatement, daoFramePameTransmission);
	}

	public static void closeConn(ResultSet rSet, PreparedStatement preparedStatement, Connection connection)
			throws FramErrorProcessing {
		try {
			if (rSet != null) {
				if (!rSet.isClosed()) {
					rSet.close();
				}
			}
			if (preparedStatement != null) {
				if (!preparedStatement.isClosed()) {
					preparedStatement.close();
				}
			}
		} catch (SQLException e) {
			throw new FramErrorProcessing(e);
		} finally {
			try {
				connection.close();
				System.out.println("關閉鏈接");
			} catch (SQLException e) {
				throw new FramErrorProcessing(e);
			}
		}
	}

	public static SqlPrecompileParameterInterface InitlaztationObjects(List<SqlPrecompileModel> list) {
		for (SqlPrecompileModel sqlPrecompileModel : list) {
			sqlPrecompileInterface.AddNumberValue(sqlPrecompileModel.getColumnName(),
					sqlPrecompileModel.getNumber().intValue(), sqlPrecompileModel.getObject());
		}
		return (SqlPrecompileParameterInterface) sqlPrecompileInterface;
	}

	public static <T, K> int sqlJdbcBatchUpdate(IcyDataTemplate icyDataTemplate,
			DaoFramePameTransmission<T, K> daoFramePameTransmission) throws Exception {
		List<List<SqlPrecompileModel>> list = daoFramePameTransmission.getSqlPrecompileParameterInterface()
				.getParameters();
		List<Object[]> lists = new ArrayList<Object[]>();
		int i = 1;
		for (List<SqlPrecompileModel> set : list) {
			Iterator<SqlPrecompileModel> iterator = set.iterator();
			List<Object> list2 = new ArrayList<Object>();
			System.out.println("線程：" + Thread.currentThread().getId() + "第" + i + "行的數據量:" + set.size());
			while (iterator.hasNext()) {
				SqlPrecompileModel sqlPrecompileModel = iterator.next();
				list2.add(sqlPrecompileModel.getObject());
			}
			i++;
			lists.add(list2.toArray());
		}
		daoFramePameTransmission.getSqlPrecompileParameterInterface().CleanParameters();
		return icyDataTemplate.batchUpdate(daoFramePameTransmission.SQL, lists).length;
	}

	public static <T, K> int sqlJdbcUpdate(IcyDataTemplate icyDataTemplate,
			final DaoFramePameTransmission<T, K> daoFramePameTransmission, boolean ifReturnId) throws SQLException {
		List<SqlPrecompileModel> sIterator = daoFramePameTransmission.getSqlPrecompileParameterInterface()
				.getSqlPrecompileModels();
		Iterator<SqlPrecompileModel> iterator = sIterator.iterator();
		final List<Object> list = new ArrayList<Object>();
		while (iterator.hasNext()) {
			SqlPrecompileModel sqlPrecompileModel = iterator.next();
			list.add(sqlPrecompileModel.getObject());
		}
		int in = 0;
		if (ifReturnId) {
			KeyHolder keyHolder = new GeneratedKeyHolder();
			icyDataTemplate.update(new PreparedStatementCreator() {
				public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
					PreparedStatement ps = connection.prepareStatement(daoFramePameTransmission.SQL,
							Statement.RETURN_GENERATED_KEYS);
					int i = 1;
					for (Object object : list) {
						ps.setObject(i, object);
						i++;
					}
					return ps;
				}
			}, keyHolder);
			in = keyHolder.getKey().intValue();
		} else {
			in = icyDataTemplate.update(daoFramePameTransmission.SQL, list.toArray());
		}
		daoFramePameTransmission.getSqlPrecompileParameterInterface().CleanSqlPrecompileModels();
		return in;
	}

	static Map<String, FrameDataSourceController> dataSourceRW = newHashMap();

	public static FrameStackTraceElement iniTraceElement() {
		return new FrameStackTraceElementImpl();
	}

	public static Map<String, FrameDataSourceController> getDataSourceRW() {
		return dataSourceRW;
	}

	public static void setDataSourceRW(Map<String, FrameDataSourceController> dataSourceRW) {
		DaoFrameConntroller.dataSourceRW = dataSourceRW;
	}

	/**
	 * 判斷類裡面有沒有一對多 或者一對一的關係
	 */
	public static <T, K> void detectionBeanOneToMays(DaoFrameDMLBaseTransmission daoFrameDMLBaseTransmission,
			DaoFramePameTransmission<T, K> daoFramePameTransmission) {
		FramAboutMay framAboutMay = new FramAboutMay();
		Field[] fields = daoFrameDMLBaseTransmission.getClassName().getDeclaredFields();
		setFramAboutMay(framAboutMay, fields);
		daoFramePameTransmission.setFramAboutMay(framAboutMay);
	}

	public static void setFramAboutMay(FramAboutMay framAboutMay, Field[] fields) {
		for (Field field : fields) {
			Boolean bool = false;
			Annotation[] annotations = field.getAnnotations();
			for (Annotation annotation : annotations) {
				if (FrameOneToMay.class.equals(annotation.annotationType())) {
					framAboutMay.getFrameOneToMays().add(field.getAnnotation(FrameOneToMay.class));
					bool = true;
				} else if (FrameOneToOne.class.equals(annotation.annotationType())) {
					framAboutMay.getFrameOneToOnes().add(field.getAnnotation(FrameOneToOne.class));
					bool = true;
				}
			}
			if (bool) {
				Class<?> clas2 = field.getType();
				Class<?> class3 = null;
				if (Collection.class.isAssignableFrom(clas2)) {
					class3 = getListT(field);
				} else {
					class3 = field.getType();
				}
				setFramAboutMay(framAboutMay, class3.getDeclaredFields());
			}
		}
	}

	public static Class<?> getListT(Field field) {
		Type genericType = field.getGenericType();
		if (genericType instanceof ParameterizedType) {
			ParameterizedType pt = (ParameterizedType) genericType;
			Class<?> genericClazz = (Class<?>) pt.getActualTypeArguments()[0];
			return genericClazz;
		} else {
			return null;
		}

	}

	/**
	 * 選擇數據策略
	 */
	public static void getIdenticalData(FrameBeansModels frameBeansModels, String... segmentation)
			throws FramErrorProcessing {
		List<Map<String, Object>> list = frameBeansModels.getList();
		try {
			for (String string : segmentation) {
				Map<String, Integer> map2 = newHashMap();
				for (Map<String, Object> map3 : list) {

					if (map3.get(string) != null) {
						String str = map3.get(string).toString();
						if (map2.isEmpty() || map2.get(str) == null) {
							map2.put(map3.get(string).toString(), 1);
						} else {
							map2.put(str, map2.get(str) + 1);
						}
					}

				}
				Iterator<Map<String, Object>> it = list.iterator();
				while (it.hasNext()) {
					Map<String, Object> map = it.next();
					if (map.get(string) != null) {
						String str = map.get(string).toString();
						int in = map2.get(str);
						if (in > 1) {
							map2.put(str, map2.get(str) - 1);
							it.remove();
						}
					}
				}

			}
		} catch (Exception e) {
			throw new FramErrorProcessing(e, "主鍵錯誤");
		}

	}

	/**
	 * 生成一對一和一對多的語句
	 */
	public static <T, K> void SqlIfBeanOneToMays(DaoFrameDMLBaseTransmission daoFrameDMLBaseTransmission,
			DaoFramePameTransmission<T, K> daoFramePameTransmission) {
		if (!WhetherToEmpty.ObjectWhetherToEmpty(daoFramePameTransmission.getFramAboutMay())) {
			if (daoFramePameTransmission.getFramAboutMay().IfSize()) {
				SqlBeanOneToMays(daoFrameDMLBaseTransmission, daoFramePameTransmission);
				// daoFramePameTransmission.setFrameDataSqlDMLUse(FrameDataSqlDMLUse.SelectMayAndOne);
			}
		}
	}

	public static <T, K> void SqlBeanOneToMays(DaoFrameDMLBaseTransmission daoFrameDMLBaseTransmission,
			DaoFramePameTransmission<T, K> daoFramePameTransmission) {

		String tables = daoFrameDMLBaseTransmission.getTableName();
		FramAboutMay framAboutMay = daoFramePameTransmission.getFramAboutMay();
		List<FrameOneToMay> list = framAboutMay.getFrameOneToMays();
		List<FrameOneToOne> list2 = framAboutMay.getFrameOneToOnes();
		for (FrameOneToMay frameOneToMay : list) {
			String tabaleName = frameOneToMay.tableName();
			String oneColumn = frameOneToMay.oneColumn();
			String mayColumn = frameOneToMay.mayColumn();
			if (!mayColumn.contains(".")) {
				mayColumn = tabaleName + "." + mayColumn;
			}
			tables += " left join " + tabaleName + " on " + oneColumn + " =" + mayColumn;
		}
		for (FrameOneToOne frameOneToOne : list2) {
			String tabaleName = frameOneToOne.tableName();
			String tocolumn = frameOneToOne.ToColumn();
			String primaryKey = frameOneToOne.columnPrimaryKey();
			if (!primaryKey.contains(".")) {
				primaryKey = tabaleName + "." + primaryKey;
			}
			tables += " left join   " + tabaleName + " on " + tocolumn + " =" + primaryKey;
		}
		daoFrameDMLBaseTransmission.setTableName(tables);
	}

	static Map<String, FrameRedisCache> redisCacheAnnotation = newHashMap();

	public static boolean IsRedisCacheAnnotationKey(String key) {
		return redisCacheAnnotation.containsKey(key);
	}

	public static void PutRedisCacheAnnotation(String key, FrameRedisCache value) {
		redisCacheAnnotation.put(key, value);
	}

	public static FrameRedisCache getRedisCacheAnnotation(String key) {
		return redisCacheAnnotation.get(key);

	}

}
